package org.testis.gui.mvc.controller.dynamicmap;

import org.testis.gui.mvc.controller.*;
import org.testis.gui.mvc.model.dynamicmap.DynamicMapModel;
import org.testis.gui.mvc.utilities.PageParserObject;
import org.testis.gui.mvc.utilities.ParameterTableModel;
import org.testis.gui.mvc.view.dynamicmap.DynamicMapView;
import org.testis.utils.tree.MyDefaultMutableTreeNode;
import java.util.HashMap;
import org.orm.PersistentException;
import org.orm.PersistentTransaction;
import org.testis.orm.classes.T_bed_firmware;
import org.testis.orm.classes.T_bed_firmwareCriteria;
import org.testis.orm.classes.T_dmap_designtree;
import org.testis.orm.classes.T_dmap_grouptypeCriteria;
import org.testis.orm.classes.T_dmap_typeCriteria;
import org.testis.orm.manager.TestisDbPersistentManager;
import org.testis.orm.refinedclasses.DynamicMapDesignTreeNode;
import org.testis.orm.refinedclasses.DynamicMapObject;
import org.testis.orm.refinedclasses.DynamicMapParameter;
import org.testis.utils.middleware.DynamicMap;
import org.testis.utils.parametermodel.ParameterModel;
import org.testis.utils.tree.TreeNode;

/**
 *
 * @author Cahit Emir Erel
 */
public class DynamicMapController extends AbstractController implements SaveAble,
        DynamicMapAddable {

    public static final String CHANGE_TYPE = "Type";
    public static final String CHANGE_GROUP_TYPE = "GroupType";
    public static final String CHANGE_PARAMETER = "Parameter";
    public static final String CHANGE_VALUE = "Value";
    public static final String CHANGE_NAME = "Name";
    public static final String ADD_PARAMETER = "AddParameterToList";
    public static final String REMOVE_SELECTED_PARAMETER =
            "RemoveSelectedParameterFromList";
    public static final String REMOVE_ALL_PARAMETERS =
            "RemoveAllParametersFromList";
    public static final String SELECT_PARAMETER = "SelectedParameter";
    public static final String LOAD_PARAMETER_TABLE = "ParameterTable";
    public static final String SHOW_ADD_DYNAMIC_MAP = "DynamicMapVisibility";
    private DynamicMapDesignTreeNode m_selectedNode = null;

    public DynamicMapController() {
        super();
    }

    public void operationNewDynamicMap(String groupType) {
        initialize(false,
                true);
        setModelProperty(CHANGE_GROUP_TYPE,
                groupType);
        setModelProperty(CHANGE_TYPE,
                "UIDeviceMapContainer");
        openWindow();
    }

    public void operationAddDynamicMap(String groupType) {
        initialize(false,
                false);
        setModelProperty(CHANGE_GROUP_TYPE,
                groupType);
        m_selectedNode = (DynamicMapDesignTreeNode) operationGetSelectedNode().
                getUserObject();
        openWindow();
    }

    public void initialize(boolean editMode,
            boolean addNewContainer) {
        ParameterTableModel temp = new ParameterTableModel();
        DynamicMapModel dynamicMapModel = new DynamicMapModel(temp);
        DynamicMapView dynamicMapView = new DynamicMapView(DynamicMapControllerList.newInstance().
                getParentFrame(),
                true,
                editMode,
                addNewContainer,
                temp);
        addModel(dynamicMapModel);
        addView(dynamicMapView);
        dynamicMapView.pack();
    }

    public void operationEditMapObject(DynamicMapDesignTreeNode node) {
        initialize(true,
                false);
        DynamicMapObject designpart = node.getObject();
        setModelProperty(CHANGE_GROUP_TYPE,
                designpart.getGroupName());
        setModelProperty(CHANGE_TYPE,
                designpart.getTypeName());
        DynamicMapParameter[] list = designpart.getParameters();
        for (int i = 0; i < list.length; i++) {
            setModelProperty(ADD_PARAMETER,
                    list[i]);
        }
        m_selectedNode = node;
        setModelProperty(CHANGE_NAME,
                designpart.getName());
    }

    public void openWindow() {
        setModelProperty(SHOW_ADD_DYNAMIC_MAP,
                true);
    }

    public MyDefaultMutableTreeNode operationGetSelectedNode() {
        return DynamicMapControllerList.newInstance().
                getDynamicMapTreeController().operationGetSelectedNode();
    }

    public void operationAddNewObject(String name,
            ParameterTableModel parameters,
            String type,
            boolean isAddNewContainer) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("name",
                name);
        params.put("parameters",
                parameters);
        params.put("type",
                type);
        DynamicMapDesignTreeNode parent = null;
        if (!isAddNewContainer) {
            parent = DynamicMapControllerList.newInstance().
                    getDynamicMapTreeController().operationGetSelectedDesignPart();
        }
        DynamicMapControllerList.newInstance().getDynamicMapTreeController().
                operationHandleAdd(this,
                parent,
                params);
    }

    public void operationSaveNewObject(String name,
            String type,
            ParameterTableModel parameters) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("name",
                name);
        params.put("type",
                type);
        params.put("parameters",
                parameters);
        DynamicMapControllerList.newInstance().getDynamicMapTreeController().
                operationHandleClones(this,
                m_selectedNode,
                params);
    }

    public void operationParseNewObject(PageParserObject ppo,
            PageParserObject parentPpo,
            MyDefaultMutableTreeNode node) {
        DynamicMapControllerList.newInstance().getDynamicMapTreeController().
                operationSelectDesignPart(node,
                0);
        try {
            PersistentTransaction t = TestisDbPersistentManager.instance().
                    getSession().beginTransaction();
            try {
                DynamicMapDesignTreeNode parentNode =
                        (DynamicMapDesignTreeNode) node.getUserObject();
                DynamicMapObject parentObject = parentNode.getObject();
                DynamicMapParameter parentParam =
                        parentObject.getParameterByName("Id");
                if (parentPpo != null && parentParam.getReference().getValue().
                        equals(parentPpo.getParameterByName("Id"))) {
                    String value = ppo.getParameterByName("Id");
                    for (int i = 0; i < node.getChildCount(); i++) {
                        MyDefaultMutableTreeNode child = node.getChildAt(i);
                        DynamicMapDesignTreeNode childnode =
                                (DynamicMapDesignTreeNode) child.getUserObject();
                        DynamicMapObject object = childnode.getObject();
                        DynamicMapParameter param =
                                object.getParameterByName("Id");
                        if (param.getReference().getValue().equals(value)) {
                            operationEditMapObject(childnode);
                        } else {
                            initialize(false,
                                    false);
                            T_dmap_grouptypeCriteria t_dmap_grouptypeCriteria =
                                    new T_dmap_grouptypeCriteria();
                            t_dmap_grouptypeCriteria.createT_dmap_typeCriteria().name.eq(ppo.getType());
                            String groupName = t_dmap_grouptypeCriteria.uniqueT_dmap_grouptype().
                                    getName();
                            setModelProperty(CHANGE_GROUP_TYPE,
                                    groupName);
                        }
                    }
                } else {
                    initialize(false,
                            false);
                    T_dmap_grouptypeCriteria t_dmap_grouptypeCriteria =
                            new T_dmap_grouptypeCriteria();
                    t_dmap_grouptypeCriteria.createT_dmap_typeCriteria().name.eq(
                            ppo.getType());
                    String groupName = t_dmap_grouptypeCriteria.uniqueT_dmap_grouptype().
                            getName();
                    setModelProperty(CHANGE_GROUP_TYPE,
                            groupName);
                }
                String oldType = (String) getModelProperty(CHANGE_TYPE);
                if (oldType == null) {
                    setModelProperty(CHANGE_TYPE,
                            ppo.getType());
                } else {
                    if (!oldType.equals(ppo.getType())) {
                        setModelProperty(CHANGE_TYPE,
                                ppo.getType());
                    }
                }
                setModelProperty(CHANGE_NAME,
                        ppo.getRealName());
                ParameterModel[] params = new ParameterModel[ppo.getParameterList().
                        size()];
                params = ppo.getParameterList().toArray(params);
                for (int j = 0; j < params.length; j++) {
                    T_dmap_typeCriteria t_dmap_typeCriteria =
                            new T_dmap_typeCriteria();
                    t_dmap_typeCriteria.name.eq(ppo.getType());
                    t_dmap_typeCriteria.createT_dmap_paramsCriteria().name.eq(
                            params[j].getParameter());
                    if (t_dmap_typeCriteria.uniqueResult() != null) {
                        setModelProperty(ADD_PARAMETER,
                                params[j]);
                    }
                }
                openWindow();
                t.commit();
            } catch (PersistentException ex) {
                t.rollback();
            } catch (Exception ex) {
                ex.printStackTrace();
                t.rollback();
            } finally {
                TestisDbPersistentManager.instance().disposePersistentManager();
            }
        } catch (PersistentException ex) {
        } catch (Exception ex) {
            ex.printStackTrace();

        }
    }

    public String[] operationGetTypes(String groupType) {
        String[] result;
        String[] temp = DynamicMap.newInstance().getTypes(groupType);
        if (groupType.equals("Container")) {
            result = new String[temp.length - 1];
            for (int i = 0, j = 0; i < temp.length; i++) {
                if (!(temp[i].equals("UIDeviceMapContainer"))) {
                    result[j] = temp[i];
                    j++;
                }
            }
        } else {
            result = temp;
        }
        return result;
    }

    public String[] operationGetParameters(String type) {
        return DynamicMap.newInstance().getParameters(type);
    }

    public String[] operationGetAbstractValues(String type) {
        return DynamicMap.newInstance().getAbstractValues(type);
    }

    public void operationChangeName(String name) {
        setModelProperty(CHANGE_NAME,
                name);
    }

    public void operationCloseWindow() {
        this.cleanAll();
    }

    public void operationChangeParameter(String parameter) {
        setModelProperty(CHANGE_PARAMETER,
                parameter);
    }

    public String operationGetValue() {
        return (String) getModelProperty(CHANGE_VALUE);
    }

    public boolean operationChangeValueForLanguageVariable(String value) {
        String parameter = (String) getModelProperty(CHANGE_PARAMETER);
        System.out.println(parameter);
        if (parameter != null && !parameter.equals("")) {
            setModelProperty(CHANGE_VALUE,
                    value);
            operationAddParameter();
            return true;
        }
        return false;

    }

    public void operationChangeValue(String value) {
        setModelProperty(CHANGE_VALUE,
                value);
    }

    public void operationChangeGroupType(String groupType) {
        setModelProperty(CHANGE_GROUP_TYPE,
                groupType);
    }

    public void operationChangeType(String type) {
        setModelProperty(CHANGE_TYPE,
                type);
    }

    public void operationAddParameter() {
        setModelProperty(ADD_PARAMETER,
                true);
    }

    public void operationAddParameter(String parameterName) {
        setModelProperty(ADD_PARAMETER,
                parameterName);
    }

    public void operationRemoveParameter(Integer selectedParameter) {
        setModelProperty(REMOVE_SELECTED_PARAMETER,
                selectedParameter);
    }

    public void operationRemoveAllParameters() {
        setModelProperty(REMOVE_ALL_PARAMETERS,
                true);
    }

    public void operationGetLanguageVariables() {
        DynamicMapDesignTreeNode root = DynamicMapControllerList.newInstance().
                getDynamicMapTreeController().operationGetRootOfSelectedNode();
        if (root != null) {
            T_dmap_designtree node = root.getReference();
            T_bed_firmwareCriteria cri;
            try {
                cri = new T_bed_firmwareCriteria();
                cri.deviceMapId.eq(node.getId());
                T_bed_firmware[] firmwares = cri.listT_bed_firmware();
                if (firmwares!=null && firmwares.length > 0) {
                    int deciveAbstractId = firmwares[0].getDevice().getAbstract().
                            getId();
                    TestDesignControllerList.newInstance().
                            getLanguageVariablesController().
                            startLoader(deciveAbstractId);
                } else {
                    TestDesignControllerList.newInstance().getTreeController().
                            operationGenerateErrorMessage(
                            "No firmware found for the selected dynamic map...",
                            "Error!");
                }
            } catch (PersistentException ex) {
                ex.printStackTrace();
                TestDesignControllerList.newInstance().getTreeController().
                        operationGenerateErrorMessage(
                        "No firmware found for the selected dynamic map...",
                        "Error!");
            }


        } else {
            TestDesignControllerList.newInstance().getTreeController().
                    operationGenerateErrorMessage(
                    "Select a dynamic map object to use language variables...",
                    "Warning!");
        }

    }

    @Override
    public boolean operationSave(HashMap<String, Object> params,
            TreeNode node,
            boolean dynamicSaveOnly) {
        return (DynamicMap.newInstance().operationSaveNewObject(params,
                (DynamicMapDesignTreeNode) node));
    }

    @Override
    public DynamicMapDesignTreeNode operationAddObject(HashMap<String, Object> params,
            TreeNode node, int childIndex) {
        DynamicMapDesignTreeNode nodeToAdd = DynamicMap.newInstance().
                operationAddNewObject(params,
                (DynamicMapDesignTreeNode) node, childIndex);
        return nodeToAdd;
    }

    @Override
    public boolean isValidSave(HashMap<String, Object> params, TreeNode node) {
        return true;
    }

    @Override
    public boolean isValidAdd(HashMap<String, Object> params, TreeNode node) {
        return true;
    }
}
